package system;

import java.io.IOException;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import system.common.ApplicationContextBean;
import system.common.Arguments;
import system.common.Constants;
import system.service.DB10_iDeskService;
import system.service.DB1_WebkeeperService;
import system.service.DB2_MsgIService;
import system.service.DB3_DbIService;
import system.service.DB4_PrivacyIService;
import system.service.DB5_NetKeyService;
import system.service.DB6_RedcastleService;
import system.service.DB7_PowerBrokerService;
import system.service.DB8_TxLoggingService;
import system.service.DB9_PortalLoginService;
import system.service.ExportService;
import collector.core.CollectConstants;
import collector.core.TaskConstVO;
import collector.core.config.ConfigModule;
import collector.core.util.DateUtil;
import collector.core.util.JobTaskUtil;
import collector.core.util.StringUtil;
import collector.task.JobStateVO;

/**
 * <pre>
 * Class : system.Execute / Execute.java
 * 	Define Class Object : 
 * <br>
 * </pre>
 * @author ytjeong / apexcns,Inc.
 * @author hwanLee / apexcns,Inc.
 * @version 1.0
 * @see javadoc
 * @since 2012. 9. 20.
 */
public class Execute { 
	private static Logger _log = LoggerFactory.getLogger(Execute.class);
	private static final String _LogPrefixStr = CollectConstants.LOGGER_MODULE_NAME_JMC + CollectConstants.LOGGER_MODULE_NAME_AFTFIX;//"mod-JOB Log> ";
	
	public static void main(String[] args) {
	    JobStateVO jsVo = new JobStateVO();	// 작업 정보를 담을 객체 생성
	    Execute exc = new Execute();
	    try {
//	    	exc.doTimeTest(args);
	    	if (args[0].equals("VIEW_STATE")) {
	    		JobTaskUtil.getModuleJobState(args[1]);
	    	} else if (args[0].equals("TIME_TEST")) {
	    		exc.doTimeTest(args);
	    	} else {
	    		jsVo = exc.doMain(args, true); // TODO::임시 true 처리
	    		
				_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
				_log.info(_LogPrefixStr + " Task result :: " + jsVo.toStringDisplay());
				_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
	    	}
	    } catch (Exception e) {
			System.err.println("main exception :: " + e.getMessage());
			_log.error(_LogPrefixStr + "------------------------------------------------------------------------------------");
			_log.error(_LogPrefixStr + "main exception :: ", e);
			_log.error(_LogPrefixStr + "------------------------------------------------------------------------------------");
	    }
	    System.exit(1);
	}
	
	@SuppressWarnings("unused")
	public void doTimeTest(String[] args) throws Exception {
		String startTime = "201208280000";
		String endTime = "201208282359";
		String tempStartTime = startTime;
		String tempEndTime;
		
		Date d;
		DateUtil.setDefaultDateFormat("yyyyMMddHHmm");
		try {
			_log.info(_LogPrefixStr + "----[Time Test]---------------------------------------------------------------------");
			for (int i = 1; i < 49; i++) {
				d = Constants.simDf_Min.parse(startTime);
				tempEndTime = DateUtil.dateAddFormat(Calendar.MINUTE, (i * 30), d);
				if (i == 48) {
					_log.info(_LogPrefixStr + " " + tempEndTime + " ~ " + endTime);
				} else {
					_log.info(_LogPrefixStr + " " + tempEndTime + " ~ " + tempEndTime);
				}
				int time = Integer.parseInt(tempEndTime.substring(11, 13));
				if (time % 2 != 0) {
					time = time - 1;
				}
				String tableTimeName = "0" + time;
				_log.info(_LogPrefixStr + " " + tableTimeName.substring((tableTimeName.length() - 2), tableTimeName.length()));
				d = Constants.simDf_Min.parse(tempEndTime);
				tempStartTime = DateUtil.dateAddFormat(Calendar.MINUTE, 1, d);
			}
			_log.info(_LogPrefixStr + "------------------------------------------------------------------------------------");
		} catch (ParseException e) {
			e.printStackTrace();
		}
		System.exit(1);
	}
	
	public JobStateVO doMain(String[] args, boolean state) throws Exception {
	    JobStateVO jsVo = new JobStateVO();	// 작업 정보를 담을 객체 생성
	    String retMsg = null;
	    
	    jsVo.setJobAuto(state);
	    
		Arguments arguments = new Arguments();
		String jobIDs = args[0];
		String durationType = null;
		String scheduleTime = null;
		String durationValue = null;
		
		Date nowDate = new Date(DateUtil.now().getTime());
		
		arguments.setParameter0(jobIDs);
		jsVo.setJobIDs(jobIDs);
		jsVo.setScheduleTime(nowDate);
		// 코드 수정 - CODE_JOB_STATE_DO [By Lee 2012.09.22]
		jsVo.setJobState(CollectConstants.CODE_JOB_STATE_DO);
		
		switch (args.length) {
		case 1:
			arguments.setParameter1("DAY");
			if (jobIDs.equals("TX_LOGGING_01")) {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, -2, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, -2, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
			} else {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, -1, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, -1, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
			}
			break;
		case 2:
			durationType = args[1];
		    // Validation Check
			if (!durationType.equals("DAY") && !durationType.equals("HOUR") && !durationType.equals("MIN") && !durationType.equals("SEC")) {
		    	retMsg = "incorrect command :: len2, argument-2 [" + durationType + "]";
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
				return jsVo;
			}
			arguments.setParameter1(durationType);
			// 코드 추가 - Parameter2, Parameter3 설정 [By Lee 2012.09.21]
			if (durationType.equals("DAY")) {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Day.format(nowDate), "yyyyMMdd"));
			} else if (durationType.equals("HOUR")) {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Hour.format(nowDate), "yyyyMMddHH"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Hour.format(nowDate), "yyyyMMddHH"));	
			} else if (durationType.equals("MIN")) {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Min.format(nowDate), "yyyyMMddHHmm"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Min.format(nowDate), "yyyyMMddHHmm"));	
			} else if (durationType.equals("SEC")) {
				arguments.setParameter2(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Sec.format(nowDate), "yyyyMMddHHmmss"));
				arguments.setParameter3(DateUtil.dateAddFormat(Calendar.DATE, 0, Constants.simDf_Sec.format(nowDate), "yyyyMMddHHmmss"));	
			}
			break;
		case 4:
			durationType = args[1];
			scheduleTime = args[2];
			durationValue = args[3];
		    // Validation Check
			if (!durationType.equals("DAY") && !durationType.equals("HOUR") && !durationType.equals("MIN") && !durationType.equals("SEC")) {
		    	retMsg = "incorrect command :: len4, argument-2 [" + durationType + "]";
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
				return jsVo;
			}
			if ((durationType.equals("DAY") && scheduleTime.length() < 8) || (durationType.equals("HOUR") && scheduleTime.length() < 10) || (durationType.equals("MIN") && scheduleTime.length() < 12) || (durationType.equals("SEC") && scheduleTime.length() < 14)) {
		    	retMsg = "incorrect command :: len4, argument-3 [" + durationType + "," + scheduleTime + "]";
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
				return jsVo;
			}
			if (!StringUtil.isNumber(durationValue)) {
		    	retMsg = "incorrect command :: len4, argument-4 [" + durationValue + "]";
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
				return jsVo;
			}
			Date d;
			String args1 = durationType;
			String args2 = "";
			String args3 = "";
			try {
				if (args1.equals("DAY")) {
					d = Constants.simDf_Day.parse(scheduleTime.substring(0, 8));
					DateUtil.setDefaultDateFormat("yyyyMMdd");
					args2 = DateUtil.dateAddFormat(Calendar.DATE, (1 - Integer.parseInt(durationValue)), d);
					args3 = DateUtil.dateAddFormat(Calendar.DATE, 0, d);
				} else if (args1.equals("HOUR")) {
					d = Constants.simDf_Hour.parse(scheduleTime.substring(0, 10));
					DateUtil.setDefaultDateFormat("yyyyMMddHH");
					args2 = DateUtil.dateAddFormat(Calendar.HOUR, (1 - Integer.parseInt(durationValue)), d);
					args3 = DateUtil.dateAddFormat(Calendar.HOUR, 0, d);
				} else if (args1.equals("MIN")) {
					d = Constants.simDf_Min.parse(scheduleTime.substring(0, 12));
					DateUtil.setDefaultDateFormat("yyyyMMddHHmm");
					args2 = DateUtil.dateAddFormat(Calendar.MINUTE, (1 - Integer.parseInt(durationValue)), d);
					args3 = DateUtil.dateAddFormat(Calendar.MINUTE, 0, d);
				} else if (args1.equals("SEC")) {
					d = Constants.simDf_Sec.parse(scheduleTime.substring(0, 14));
					DateUtil.setDefaultDateFormat("yyyyMMddHHmmss");
					args2 = DateUtil.dateAddFormat(Calendar.SECOND, (1 - Integer.parseInt(durationValue)), d);
					args3 = DateUtil.dateAddFormat(Calendar.SECOND, 0, d);
				}
				arguments.setParameter1(args1);
				arguments.setParameter2(args2);
				arguments.setParameter3(args3);
				
				jsVo.setJobDurationValue(Integer.parseInt(durationValue));
			} catch (ParseException e) {
				e.printStackTrace();
		    	retMsg = "command parse exception :" + e.getMessage();
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
				return jsVo;
			}
			break;
		default:
	    	retMsg = "incorrect command";
			System.err.println(retMsg);
			jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
			return jsVo;
		}
		_log.info(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		_log.info(_LogPrefixStr + "|" + " " + jobIDs + " > arguments 1 :: " + arguments.getParameter0());
		_log.info(_LogPrefixStr + "|" + " " + jobIDs + " > arguments 2 :: " + arguments.getParameter1());
		_log.info(_LogPrefixStr + "|" + " " + jobIDs + " > arguments 3 :: " + arguments.getParameter2());
		_log.info(_LogPrefixStr + "|" + " " + jobIDs + " > arguments 4 :: " + arguments.getParameter3());
		_log.info(_LogPrefixStr + "|" + "------------------------------------------------------------------------------------");
		
		// 코드 수정 - jobCondStartTime, jobCondEndTime [By Lee 2012.09.23]
		jsVo.setJobCondStartTime(DateUtil.trim(arguments.getParameter2()));
		jsVo.setJobCondEndTime(DateUtil.trim(arguments.getParameter3()));

		jsVo = doService(jsVo, arguments, jobIDs);
		
		return jsVo;
	}
	
	// 함수 추가 - doService [By Lee 2012.09.23]
	public JobStateVO doService(JobStateVO jsVo, Arguments arguments, String jobIDs) throws IOException {
		String retMsg = null;
		
		try {
			ApplicationContextBean bean = ApplicationContextBean.getInstance();
			// 코드 추가 및 수정 - TaskConstVO [By Lee 2012.09.21]
			TaskConstVO tcVo = ConfigModule.newInstance().getModuleTask(jsVo.getJobIDs());
			
			if (jobIDs.equals("WEBKEEPER_01") || jobIDs.equals("WEBKEEPER_02")) {
				DB1_WebkeeperService webkeeperService = (DB1_WebkeeperService) bean.getBean("DB1_WebkeeperService");
				jsVo = webkeeperService.runWebkeeper(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("WEBKEEPER_MIGRATE_01") || jobIDs.equals("WEBKEEPER_MIGRATE_02")) {
				DB1_WebkeeperService webkeeperService = (DB1_WebkeeperService) bean.getBean("DB1_WebkeeperService");
				jsVo = webkeeperService.runWebkeeperMigrate(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("MSG_I_01") || jobIDs.equals("MSG_I_02") || jobIDs.equals("MSG_I_03")) {
				DB2_MsgIService msgIService = (DB2_MsgIService) bean.getBean("DB2_MsgIService");
				jsVo = msgIService.runMsgI(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("DB_I_01")) {
				DB3_DbIService dbIService = (DB3_DbIService) bean.getBean("DB3_DbIService");
				jsVo = dbIService.runDbI(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("PRIVACY_I_01")) {
				DB4_PrivacyIService privacyIService = (DB4_PrivacyIService) bean.getBean("DB4_PrivacyIService");
				jsVo = privacyIService.runPrivacyI(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("NET_KEY_01") || jobIDs.equals("NET_KEY_02")) {
				DB5_NetKeyService netKeyService = (DB5_NetKeyService) bean.getBean("DB5_NetKeyService");
				jsVo = netKeyService.runNetKey(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("REDCASTLE_01") || jobIDs.equals("REDCASTLE_02") || jobIDs.equals("REDCASTLE_03")) {
				DB6_RedcastleService redcastleService = (DB6_RedcastleService) bean.getBean("DB6_RedcastleService");
				jsVo = redcastleService.runRedcastle(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("POWERBROKER_01") || jobIDs.equals("POWERBROKER_02")) {
				DB7_PowerBrokerService powerBrokerService = (DB7_PowerBrokerService) bean.getBean("DB7_PowerBrokerService");
				jsVo = powerBrokerService.runPowerBroker(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("TX_LOGGING_01")) {
				DB8_TxLoggingService txLoggingService = (DB8_TxLoggingService) bean.getBean("DB8_TxLoggingService");
				jsVo = txLoggingService.runTxLogging(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("PORTAL_LOGIN_01")) {
				DB9_PortalLoginService portalLoginService = (DB9_PortalLoginService) bean.getBean("DB9_PortalLoginService");
				jsVo = portalLoginService.runPortalLogin(arguments, jsVo, tcVo);
			} else if (jobIDs.equals("IDESK_01")) {
				DB10_iDeskService iDeskService = (DB10_iDeskService) bean.getBean("DB10_iDeskService");
				jsVo = iDeskService.runIDesk(arguments, jsVo, tcVo);
			} else {
		    	retMsg = "incorrect out of command";
				System.err.println(retMsg);
				jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
			}
			ExportService.OutputStateLog(jsVo);
		} catch (Exception e) {
	    	retMsg = "bean service exception :" + e.getMessage();
			System.err.println(retMsg);
			jsVo.setFailDoneResult(CollectConstants.CODE_JOB_RESULT_CODE_FAIL, retMsg);
		}

		return jsVo;
	}
}